!function(p, e) { "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (p = "undefined" != typeof globalThis ? globalThis : p || self)._Fun = e() }
	(this, function() {
		"use strict";
		var _fun_ = {};
		function S4() {
			return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
		}
		_fun_.isBlob = function(o) {
			return o instanceof Blob;
		}
		_fun_.isBuffer = function(o) {
			return gettype.call(o) == "[object ArrayBuffer]";
		}
		_fun_.isSet = function(o) {
			return gettype.call(o) == "[object Set]";
		}
		_fun_.isType = function(o) {
			return gettype.call(o);
		}
		_fun_.isMap = function(o) {
			return gettype.call(o) == "[object Object]";
		}
		_fun_.isArray = function(o) {
			return gettype.call(o) == "[object Array]" || gettype.call(o) == "[object Arguments]";
		}
		_fun_.isArguments = function(o) {
			return gettype.call(o) == "[object Arguments]";
		}
		_fun_.isFun = function(o) {
			return gettype.call(o) == "[object Function]";
		}
		_fun_.isNULL = function(o) {
			return gettype.call(o) == "[object Null]";
		}
		_fun_.isUndefined = function(o) {
			return gettype.call(o) == "[object Undefined]";
		}
	
		_fun_.isString = function(o) {
			return gettype.call(o) == "[object String]";
		}
		_fun_.isBool = function(o) {
			return gettype.call(o) == "[object Boolean]";
		}
		_fun_.isEmpty = function(obj) {
			return (obj === undefined || obj === null) ? true : false;
		}
		_fun_.isEmptyStr = function(obj) {
			return (obj === undefined || obj === null || obj == "" || obj == "null") ? true : false;
		}
		_fun_.isEmptyMap = function(e) {
			if (e == undefined || e == null)
				return true;
			for (var t in e)
				return false;
			return true;
		}
		_fun_.isEmptyArray = function(arr) {
			if (arr = undefined || _fun_.isArray(arr) || arr.length == 0)
				return true;
			else
				return false;
		}

		_fun_.isEmptyObject = function(obj) {
			//console.log("isEmptyObject", Object.keys(obj).length)
			if (Object.keys(obj).length === 0) {
				return true;
			} else {
				return false;
			}
		}
		_fun_.isEmail = function(email) {
			var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
			return reg.test(email);
		};
		_fun_.isPhone = function(手机) {
			var reg = /^1[0-9]{10,10}$/;
			return reg.test(手机);
		};
		_fun_.isNum = function(o) {
			return gettype.call(o) == "[object Number]";
		}
		_fun_.isNumber = function(input) {
			var pattern = /^[0-9]+([.]{1}[0-9]{1,2})?$/;
			if (pattern.test(input)) {
				return true;
			} else {
				alert("请输入数值!");
				return false;
			}
		}
	//判断是否在微信浏览器打开
		_fun_.isWechat = function() {
			var ua = navigator.userAgent.toLowerCase();
			if (ua.match(/MicroMessenger/i) == "micromessenger") {
				return true;
			} else {
				return false;
			}
		}
		_fun_.isObject = function(o) {
			return o !== null && typeof o === "object";
		}
		_fun_.isDate = function(o) {
			return gettype.call(o) === "[object Date]";
		}
		_fun_.isRegExp = function(o) {
			return gettype.call(o) === "[object RegExp]";
		}
		_fun_.isError = function(o) {
			return gettype.call(o) === "[object Error]";
		}
		_fun_.isSymbol = function(o) {
			return typeof o === "symbol";
		}
		_fun_.isPromise = function(o) {
			return gettype.call(o) === "[object Promise]";
		}
		_fun_.is有效字符串 = function(str) {
			// 正则表达式，匹配以下条件的字符串：
			// 1. 不能包含空白字符（如空格、制表符、换行符等）
			// 2. 不能包含HTML标签
			var regex = /^[^<>\s]*$/;
			// 使用正则表达式的test方法进行匹配
			return regex.test(str);
		}
		
		
		_fun_.error = [];
		_fun_.clear = function() {
			_fun_.error = [];
		}

		/**
		 * @param {Object} data
		 * @param {Object} checkRule 1,10 1-10个字符长度
		 * @param {Object} errmsg
		 * 
		 */
		_fun_.chkstr = function(data, checkRule, errOrg) {
			var reg = new RegExp('^.{' + checkRule + '}$');
			if (!reg.test(data)) {
				_fun_.error.push(errOrg + '应为' + checkRule + '个字符');
			}
			return _fun_;
		}
		_fun_.chkint = function(data, errOrg) {
			var reg = /^-?[1-9][0-9]?$/;
			if (!reg.test(data)) {
				_fun_.error.push(errOrg + '不是整型数值');
			}
			return _fun_;
		}
		_fun_.chknumber = function(data, errOrg) {
			var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
			if (!reg.test(data)) {
				_fun_.error.push(errOrg + '不是数值');
			}
			return _fun_;
		}
		_fun_.chkfloat = function(data, errOrg) {
			var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
			if (!reg.test(data)) {
				_fun_.error.push(errOrg + '不是浮点数值');
				return  '不是浮点数值';
			}
			return _fun_;
		}
		_fun_.between = function(data, checkRule, errOrg) {
			var minMax = checkRule.split(',');
			minMax[0] = Number(minMax[0]);
			minMax[1] = Number(minMax[1]);
			if (data > minMax[1] || data < minMax[0]) {
				_fun_.error.push(errOrg + '不在' + checkRule + '之间');
			}
			return _fun_;
		}
		_fun_.chksame = function(data1, data2, errmsg) {
			if (data1 != data2) {
				_fun_.error.push(errmsg);
			}
			return _fun_;
		}
		_fun_.chknosame = function(data1, data2, errmsg) {
			if (data1 == data2) {
				_fun_.error.push(errmsg);
			}
			return _fun_;
		}
		_fun_.chkmail = function(data, errmsg) {
			var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
			if (!reg.test(data)) {
				_fun_.error.push(errmsg || '电子邮箱不正确');
			}
			return _fun_;
		}
		_fun_.chkphone = function(data, errmsg) {
			var reg = /^1[0-9]{10,10}$/;
			if (!reg.test(data)) {
				_fun_.error.push(errmsg || '手机号码不正确');
			}
			return _fun_;
		}
		_fun_.chkzip = function(data, errOrg) {
			var reg = /^[0-9]{6}$/;
			if (!reg.test(data)) {
				_fun_.error.push(errOrg + '不是压缩数据');
			}
			return _fun_;
		}

		_fun_.chkin = function(data, checkRule, errOrg) {
			if (checkRule.indexOf(data) == -1) {
				_fun_.error.push(errOrg + '不在' + checkRule + '中');
			}
			return _fun_;
		}
		_fun_.chknotnull = function(data, errmsg) {
			if (data == null || data.length < 1) {
				_fun_.error.push(errmsg);
			}
			return _fun_;
		}
	
		/**
	* 深度克隆
	* @param {Object} obj 待克隆的map对象
	* @param {Object} attrs 对于map类型的对象 可以限定克隆的属性 ，数组格式
	*/
		_fun_.f深度克隆 = function(obj, attrs) {
			if (undefined == obj || null == obj) return null;
			if (obj instanceof Date) {
				var copy = new Date();
				copy.setTime(obj.getTime());
				return copy;
			}
			if (obj instanceof Array) {
				var copy = [];
				for (var i = 0; i < obj.length; ++i) {
					copy.push(clone(obj[i], attrs));
				}
				return copy;
			}
			if (obj instanceof Object) {
				var copy = {};
				if (attrs == null) {
					for (var attr in obj) {
						copy[attr] = obj[attr];
					}
				} else {
					for (var a = 0; a < attrs.length; a++) {
						copy[attrs[a]] = obj[attrs[a]];
					}
				}
				return copy;
			}
			return obj;
		}

		_fun_.join = function(...str) {
			return str.join("");
		}
		//UTF-8转UTF-16
		_fun_.utf8ToUtf16 = function(s) {
			if (!s) {
				return;
			}

			var i, codes, bytes, ret = [],
				len = s.length;
			for (i = 0; i < len; i++) {
				codes = [];
				codes.push(s.charCodeAt(i));
				if (((codes[0] >> 7) & 0xff) == 0x0) {
					//单字节  0xxxxxxx
					ret.push(s.charAt(i));
				} else if (((codes[0] >> 5) & 0xff) == 0x6) {
					//双字节  110xxxxx 10xxxxxx
					codes.push(s.charCodeAt(++i));
					bytes = [];
					bytes.push(codes[0] & 0x1f);
					bytes.push(codes[1] & 0x3f);
					ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1]));
				} else if (((codes[0] >> 4) & 0xff) == 0xe) {
					//三字节  1110xxxx 10xxxxxx 10xxxxxx
					codes.push(s.charCodeAt(++i));
					codes.push(s.charCodeAt(++i));
					bytes = [];
					bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf));
					bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f));
					ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1]));
				}
			}
			return ret.join('');
		}/**
		* 对比两个Map对象的特定属性 判断是否相等
		* @param {Map} obj1 Map
		* @param {Map} obj2 Map
		* @param {Array} cols  待对比的键
		*/
		_fun_.b比较两个对象 = function(obj1, obj2, cols) {
			var keys = split(cols);
			if (keys == null) return false;
			for (var i = 0; i < keys.length; i++) {
				var field = keys[i];
				if (!equal(obj1[field], obj2[field])) {
					return false;
				}
			}
			return true;
		}

		/** 
		 * 加减yyyymm 年月
		 * @param {Object} monnum 格式：yyyymm 年月
		 * @param {Object} num 正数：添加，负数：减少
		 */
		_fun_.f加减yyyymm = function(monnum, num) {
			var ym = new Number(monnum)
			var y = parseInt(ym / 100); //2017
			var m = ym % 100; //09
			var cnt = parseInt(num / 12);
			var mnt = num % 12;
			y = y + cnt;
			if (mnt < 0) {
				y = y - 1;
				m = m + (12 + mnt);
			} else {
				m = m + mnt;
			}
			if (m > 12) {
				y = y + 1;
				m -= 12;
			}
			return (y * 100 + m).toString();
		}

		/**放大
		 * @param {Object} f
		 * @param {Object} n n如果小于10  10^n  如果大于10 就是
		 */

		_fun_.f放大 = function(f, n) {
			return f * n;
		}

		/**缩小
		 * @param {Object} f
		 * @param {Object} n
		 */

		_fun_.f缩小 = function(f, n) {
			return f / n;
		}
		/**左侧补0
		 * @param {Object} obj
		 * @param {number} length
		 */
		_fun_.左侧补0 = function(obj, length) {
			return obj.toString().padLeft(length);
		}


		/**
		 * 获取
		 */
		_fun_.getGuid = function() {
			var d = new Date().getTime();
			var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
				var r = (d + Math.random() * 16) % 16 | 0;
				d = Math.floor(d / 16);
				return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
			});
			return uuid;
		}
		_fun_.g时间戳毫秒 = function() {
			return new Date().getTime();
		}
		_fun_.g时间戳纳秒 = function() {
			var mydate = new Date;
			return mydate.getFullYear() + (mydate.getMonth() + 1) + '' + mydate.getDate() + mydate.getHours() +
				mydate.getMinutes() + mydate.getSeconds() + mydate.getMilliseconds() + Math.round(Math.random() *
					10000);
		}
		/**
		 * 把有分隔符的字符串转成数组或者对象
		 * 如果已经是数组或者对象则不用转化
		 * @param {String ，Array ，Map} obj 
		 */
		_fun_.split = function(obj, sp) {
			var props = null;
			sp = (sp == undefined || sp == null) ? "," : sp;
			if (_IS.isEmpty(obj)) return null;
			if (_IS.isString(obj))
				props = obj.split(sp);
			else
				props = obj;
			return props;
		}

		/**
		 * 测试打印json对象
		 * @param {Object} data
		 * @param {Object} note
		 */
		_fun_.f打印json = function(data, note) {
			var s = JSON.stringify(data);
			if (note == null)
				console.log(s)
			else
				console.log(note, s)
		}
		/**
		 * 测试打印map对象
		 * @param {Object} data
		 * @param {Object} note
		 */
		_fun_.f打印map = function(map) {
			for (var i in map) {
				console.log(i, JSON.stringify(map[i]));
			}
		}
		/**
		 * 判断两个参数是否值相等
		 */
		_fun_.equal = function(a, b) {
			if ((null == a && null == b) || (undefined == a && undefined == b)) return true;
			var classNameA = toString.call(a);

			if (classNameA == '[object Function]') return false;
			switch (classNameA) {
				case '[object RegExp]':
				case '[object String]':
					//进行字符串转换比较
					return '' + a === '' + b;
				case '[object Number]':
					//进行数字转换比较,判断是否为NaN
					if (+a !== +a) {
						return +b !== +b;
					}
					//判断是否为0或-0
					return +a === 0 ? 1 / +a === 1 / b : +a === +b;
				case '[object Date]':
				case '[object Boolean]':
					return +a === +b;
			}
			if (classNameA == '[object Array]') {
				for (var i = 0; i < a.length; ++i) {
					if (!equal(a[i], b[i])) return false;
				}
				return true;
			}
			if (classNameA == '[object Object]') {
				for (var i in a) {
					if (!equal(a[i], b[i])) return false;
				}
				return true;
			}
			return false;
		}



		/**
		 * 交换两个变量值
		 */

		_fun_.f交换 = function(a, a1) {
			if (_fun_.isEmpty(a) || _fun_.isEmpty(a1)) return;
			var z;
			z = a;
			a = a1;
			a1 = z;
		}

		/**
		 * 在数组arr1的第n位之前，插入arr2元素
		 * @param {Object} arr1 待插入的数组
		 * @param {Object} n  第n位之前
		 * @param {Object} arr2 插入arr2数组
		 */
		_fun_.f插入数组 = function(arr1, n, arr2) {
			if (arr2 == null || arr2 == undefined) return arr1;
			n = (n > arr1.length) ? arr1.length : (n < 0) ? arr1.length + n : n;
			for (var i = arr2.length - 1; i >= 0; i--) {
				arr1.splice(n, 0, arr2[i]);
			}
			return arr1;
		}

		/**
		 * 移动数组中的一个元素从i 到 n位后面
		 * @param {Object} arr1 数组
		 * @param {Object} i 移动前的开始位置
		 * @param {Object} n 移动前的目标位置之后
		 * @param {Object} len 移动元素个数
		 */
		_fun_.f移动元素 = function(arr1, a, n, len) {
			if (len == null || len == undefined) return arr1;
			//var a = arr1.slice(i, i + len);
			if (a == n || a < 0 || len < 1 || len > arr1.length) return arr1;
			var b;
			if (a > n) {
				b = a;
				a = n;
				n = b;
			}
			if (a + len > n) return arr1;
			var k = n - a - len;
			for (var i = len - 1; i >= 0; i--) {
				for (var j = 0; j <= k; j++) {

					var z = a + i + j;
					change(arr1, z, z + 1);
				}
			}
			return arr1;
		}


		_fun_.f交换元素 = function(arr1, a, a1) {
			if (_IS.isEmpty(arr1) || _IS.isEmpty(a) || _IS.isEmpty(a1) || _IS.isEmpty(arr1[a1]) || _IS.isEmpty(arr1[a]))
				return;
			var z
			z = arr1[a];
			arr1[a] = arr1[a1];
			arr1[a1] = z;
		}


		/**
		 * 交换数组 a位置和n位置的 元素 长度为len
		 * @param {Object} arr1
		 * @param {Object} a
		 * @param {Object} n
		 * @param {Object} len
		 */
		_fun_.f交换元素2 = function(arr1, a, n, len) {
			if (len == null || len == undefined) return arr1;
			//var a = arr1.slice(i, i + len);
			if (a == n || a < 0 || len < 1 || len > arr1.length) return arr1;
			var b;
			if (a > n) {
				b = a;
				a = n;
				n = b;
			}
			if (a + len > n) return arr1;

			for (var i = 0; i < len; i++) {
				change(arr1, a + i, n + i);
			}
			return arr1;

		}

		/**
		 * 拼接数组（不平面化）直接用join
		 * 拼接数组（只对第二层平面化） 用concat ,为空的不丢弃
		 * 参数个数可变
		 * a=[1,2,3] ,b=[3，4]
		 * c.concat(a,b) =[1,2,3,3,4]
		 */
		_fun_.f拼接 = function() {
			var arr = [];
			for (var i = 0; i < arguments.length; i++) {
				var item = arguments[i];
				if (_fun_.isArray(item)) {
					for (var j = 0; j < item.length; j++) {
						arr.push(item[j]);
					}
				} else {
					if (_fun_.isEmpty(item)) return [];
					arr.push(item);
				}
			}
			return arr;
		}
		/**
		 * 适用于 【字符串，字符串】类型
		 * 不剔除空值，
		 * @param {Object} arr
		 */
		_fun_.f去重 = function(arr) {
			var arr1 = []
			for (var i = 0; i < arr.length; i++) {
				//if (_fun_.isEmpty(arr[i])) continue;
				var flag = true;
				for (var j = 0; j < arr1.length; j++) {
					if (equal(arr1[j], arr[i])) {
						flag = false;
						break;
					}
				}
				if (flag)
					arr1.push(arr[i])
			}
			return arr1;
		}
		/**
		 * 删除空的元素
		 */
		_fun_.f去空 = function(arr1) {
			if (arr1 == null || arr1.length < 1) return [];
			var arr = [];
			for (var i = 0; i < arr1.length; i++) {
				if (arr1[i] == null || arr1[i] == undefined || arr1[i] == "") {
					continue;
				}
				arr.push(arr1[i]);
			}
			return arr;
		}
		/**
		 * 
		 * @param {Object} arr 待匹配的数组
		 * @param {Object} obj 匹配的对象
		 * find() 在ie11 之前不支持
		 */
		_fun_.f查找数组中的位置 = function(arr, obj) {
			for (var i = 0; i < arr.length; i++) {
				if (equal(arr[i], obj)) return i;
			}
			return -1;
		}

		_fun_.f查找对象 = function(arr, obj) {
			if (arr.indexOf(obj) > -1) return true;
			return false;
		}

		_fun_.f追加元素 = function(arr, key) {
			if (_fun_.isEmpty(arr))
				arr = [];
			for (var i = 0; i < arr.length; i++) {
				if (arr[i] == key) {
					return;
				}
			}
			arr.push(key);
			return arr;
		}

		//对象合并可以使用 Object.assign函数
		/**
		 * 根据属性,截取object对象的部分属性 生成新的对象
		 * @param {Object} object
		 * @param {String，Array} cols 过滤字段集合，如果为空，那么不过滤
		 * @return {Object}  返回对象
		 */
		_fun_.f合并多个对象 = function(对象集合, 列集) {
			var n1 = {};
			if (_fun_.isArray(对象集合)) {
				object = 对象集合;
				cols = 列集;

				if (_fun_.isEmptyStr(cols)) return object;
				if (!_fun_.isArray(列集))
					列集 = split(列集);
				for (var i = 0; i < 列集.length; i++) {
					n1[列集[i]] = object[列集[i]];
				}
				console.log(object, cols, 列集, "n1:", n1)
				return n1;
			} else return {};
		}

		/**合并两个对象，是merge的基础 ，兼容低版本浏览器Es5
		 * ES6 对象提供了 Object.assign()这个方法
		 * @param {Object} a
		 * @param {Object} b
		 */

		_fun_.f把B对象合入A对象 = function(a, b) {

			if (_fun_.isEmpty(b)) {
				if (_fun_.isEmpty(a))
					return {};
				else {
					return a;
				}
			} else {
				for (var k in b) {
					a[k] = b[k];
				}
				return a;
			}
		}
		/**
		 *  把b值覆盖写入a
		 */
		_fun_.f把b值覆盖写入a = function(a, b) {
			if (_fun_.isEmpty(b) || _fun_.isEmpty(a)) {
				return;
			} else {
				for (var k in a) {
					if (b[k])
						a[k] = b[k];
				}
			}
		}

		_fun_.fmt钱 = function(longmoney) {
			return Math.floor(longmoney * 1.0) / 100
		}

		_fun_.f补零 = function(s) {
			return s < 10 ? '0' + s : s;
		}
		_fun_.g现在日期 = function() {
			var myDate = new Date();

			var year = myDate.getFullYear(); //获取当前年
			var month = myDate.getMonth() + 1; //获取当前月
			var date = myDate.getDate(); //获取当前日
			var now = year + '-' + 补零(month) + "-" + 补零(date);
			return now;
		}
		_fun_.g现在时间 = function() {
			var myDate = new Date();

			var year = myDate.getFullYear(); //获取当前年
			var month = myDate.getMonth() + 1; //获取当前月
			var date = myDate.getDate(); //获取当前日

			var h = myDate.getHours(); //获取当前小时数(0-23)
			var m = myDate.getMinutes(); //获取当前分钟数(0-59)
			var s = myDate.getSeconds();

			var now = year + '-' + 补零(month) + "-" + 补零(date) + " " + 补零(h) + ":" + 补零(m) + ":" + 补零(s);
			return now;
		}
		//精度1000000
		_fun_.缩小6个0 = function(val) {
			//金额转换 分->元 保留2位小数 并每隔3位用逗号分开 1,234.56
			if (!val)
				val = 0;
			var str = (val / 1000000).toFixed(2) + '';
			var intSum = str.substring(0, str.indexOf(".")).replace(/\B(?=(?:\d{3})+$)/g, ','); //取到整数部分
			var dot = str.substring(str.length, str.indexOf(".")) //取到小数部分搜索
			var ret = intSum + dot;
			return ret;
		}

		//进度100
		_fun_.缩小2个0 = function(val) {
			//金额转换 分->元 保留2位小数 并每隔3位用逗号分开 1,234.56
			if (!val)
				val = 0;
			var str = (val / 100).toFixed(2) + '';
			var intSum = str.substring(0, str.indexOf(".")).replace(/\B(?=(?:\d{3})+$)/g, ','); //取到整数部分
			var dot = str.substring(str.length, str.indexOf(".")) //取到小数部分搜索
			var ret = intSum + dot;
			return ret;
		}

		/**
		 * 获取字符串的哈希值
		 * @param {String} str
		 * @param {Boolean} 是否区分大小写
		 * @return {Number} hashCode
		 */
		_fun_.getHashCode = function(str, 是否区分大小写) {
			是否区分大小写 = 是否区分大小写 || true;
			if (!是否区分大小写) {
				str = str.toLowerCase();
			}
			// 1315423911=b'1001110011001111100011010100111'
			var hash = 1315423911,
				i, ch;
			for (i = str.length - 1; i >= 0; i--) {
				ch = str.charCodeAt(i);
				hash ^= ((hash << 5) + ch + (hash >> 2));
			}

			return (hash & 0x7FFFFFFF);
		}
		//ASCII 转换 Unicode
		_fun_.AsciiToUnicode = function(content) {
			result = '';
			for (var i = 0; i < content.length; i++)
				result += '&#' + content.charCodeAt(i) + ';';
			alert("ASCII：" + content + "\nUnicode：" + result);
		}
		//Unicode 转换 ASCII
		_fun_.UnicodeToAscii = function(content) {
			var code = content.match(/&#(\d+);/g);
			result = '';
			for (var i = 0; i < code.length; i++)
				result += String.fromCharCode(code[i].replace(/[&#;]/g, ''));
			alert("Unicode：" + content + "\nASCII：" + result);
		}
		//UTF-16转UTF-8
		_fun_.utf16ToUtf8 = function(s) {
			if (!s) {
				return;
			}
			var i, code, ret = [],
				len = s.length;
			for (i = 0; i < len; i++) {
				code = s.charCodeAt(i);
				if (code > 0x0 && code <= 0x7f) {
					//单字节
					//UTF-16 0000 - 007F
					//UTF-8  0xxxxxxx
					ret.push(s.charAt(i));
				} else if (code >= 0x80 && code <= 0x7ff) {
					//双字节
					//UTF-16 0080 - 07FF
					//UTF-8  110xxxxx 10xxxxxx
					ret.push(
						//110xxxxx
						String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)),
						//10xxxxxx
						String.fromCharCode(0x80 | (code & 0x3f))
					);
				} else if (code >= 0x800 && code <= 0xffff) {
					//三字节
					//UTF-16 0800 - FFFF
					//UTF-8  1110xxxx 10xxxxxx 10xxxxxx
					ret.push(
						//1110xxxx
						String.fromCharCode(0xe0 | ((code >> 12) & 0xf)),
						//10xxxxxx
						String.fromCharCode(0x80 | ((code >> 6) & 0x3f)),
						//10xxxxxx
						String.fromCharCode(0x80 | (code & 0x3f))
					);
				}
			}
			return ret.join('');
		}
		_fun_.uuid = function() {
			var s = [];
			var hexDigits = "0123456789abcdef";
			for (var i = 0; i < 36; i++) {
				s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
			}
			s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
			s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
			s[8] = s[13] = s[18] = s[23] = "-";

			var uuid = s.join("");
			return uuid;
		}

		_fun_.uuid32 = function() {
			return S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4();
		}
		_fun_.g验证码 = function() {
			return S4();
		}

		_fun_.existKey = function(obj, key) {
			if (obj instanceof Object) {
				for (let attr in obj) {
					if (key == attr)
						return true;
				}
				return false;
			}
			return false
		}
		_fun_.existValue = function(obj, value) {
			if (obj instanceof Array) {
				for (let i = 0; i < obj.length; ++i) {
					if (value == obj[i])
						return true;
				}
				return false;
			}
			if (obj instanceof Object) {
				for (let attr in obj) {
					if (value == obj[attr])
						return true;
				}
				return false;
			}
			//字符串
			if ('string' == typeof obj) {
				return (obj.indexOf(value) > -1);
			}
			return false;
		}

		_fun_.clone = function(obj) {
			if (null == obj || "object" != typeof obj) return obj;
			if (obj instanceof Date) {
				var copy = new Date();
				copy.setTime(obj.getTime());
				return copy;
			}
			if (obj instanceof Array) {
				var copy = [];
				for (let i = 0; i < obj.length; ++i) {
					copy.push(clone(obj[i]));
				}
				return copy;
			}
			if (obj instanceof Object) {
				var copy = {};
				for (let attr in obj) {
					copy[attr] = clone(obj[attr]);
				}
				return copy;
			}
			return obj;
			//throw new Error("这个对象不支持拷贝.");
		}

		/**仅复制 字典中 需要的项
		 * @param {Object} 数据源
		 * @param {String} 字段数组 需要的项逗号分隔
		 * @param {Boolean} 筛排 筛选 true,排除 false
		 */
		_fun_.cloneMap = function(数据源, 字段数组, 筛排) {
			if (null == 数据源 || "object" != typeof 数据源) return 数据源;
			if (数据源 instanceof Object) {
				let copy = {};
				if (字段数组 && 字段数组.length > 0) {
					let isselect = 筛排 || true;
					for (let attr in 数据源) {
						let a = existValue(字段数组, attr)
						if (!isselect ^ a) copy[attr] = clone(数据源[attr]);
					}
				} else {
					for (let attr in 数据源) {
						copy[attr] = clone(数据源[attr]);
					}
				}
				return copy;
			}
			return 数据源;
		}


		/**
		 * 等效于Object.assign({}, ...item); 但是做了扩展
		 *  @param {Object} 目标
		 *  @param {Object} 数据源 
		 *  @param {Array} 字段数组 
		 *  @param {Boolean} 筛排 筛选 true,排除 false
		 */
		_fun_.extend = function(目标, 数据源, 字段数组, 筛排) {
			if (字段数组 && 字段数组.length > 0) {
				let isselect = 筛排 || true;
				for (let i = 0; i < 字段数组.length; i++) {
					let key = 字段数组[i];
					let a = (key != null && key != '' && 数据源.hasOwnProperty(key));
					if (!isselect ^ a) 目标[key] = 数据源[key];
				}
			} else {
				for (let prp in 数据源) {
					目标[prp] = 数据源[prp];
				}
			}
		}




		// function Assembly(obj) {
		// 	var name = "";
		// 	for (var name1 in obj)
		// 		name += name1 + ":" + obj[name1] + "\n";
		// 	///console.log("反射", name);
		// }
		_fun_.round2 = function(number, fractiondigits) {
			return round(number * Math.pow(10, fractiondigits)) / Math.pow(10, fractiondigits);
		};
		_fun_.log = function(...a) {
			console.log(a);
		}
		//封装 console.log 函数
		_fun_.printLog = function(title, info) {
			window.console && console.log(title, info);
		}
		_fun_.extend = function(obj, source) {
			for (property in source) {
				obj[property] = source[property];
			}
			return _fun_;
		}
		_fun_.g生成十六进制字符串 = function(n位) {
			let result = '';
			const characters = '0123456789ABCDEF';

			for (let i = 0; i < n位; i++) {
				const randomIndex = Math.floor(Math.random() * characters.length);
				result += characters[randomIndex];
			}

			return result;
		}
		function post(url, head, data, success, error) {
			let xhr;
			if (window.XMLHttpRequest) {
				xhr = new XMLHttpRequest() // ie7+等现代浏览器
			} else if (window.ActiveXObject) { // ie5/6，老版Opera
				xhr = new ActiveXObject('Microsft.XMLHTTP')
			}
			xhr.open('POST', url, true);
			for (let [key, value] of Object.entries(head)) {
				//console.log(key, value);
				xhr.setRequestHeader(key, value);
			}

			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4) {
					if (xhr.status == 200) {
						var response = xhr.responseText;
						// 在这里处理服务器响应
						success(response, xhr.status);
					} else if (this.status == 404) {
						console.log('网页不存在')
					} else {
						error && error(xhr.status, xhr.responseText);
					}
				}
			};
			xhr.send(JSON.stringify(data));
		};
		_fun_.postForm = function(url, head, data, success, error) {
			let mergedObj = Object.assign({}, { 'Content-Type': 'application/x-www-form-urlencoded' }, head);
			post(url, mergedObj, data, success, error);
		};
		_fun_.postJson = function(url, head, data, success, error) {
			let mergedObj = Object.assign({}, { 'Content-Type': 'application/json' }, head);
			post(url, mergedObj, data, success, error);
		};
		_fun_.postPart = function(url, head, data, success, error) {
			let mergedObj = Object.assign({}, { 'Content-Type': 'multipart/form-data' }, head);
			post(url, mergedObj, data, success, error);
		};
		_fun_.url = function(url, head, success, error) {
			let xhr;
			if (window.XMLHttpRequest) {
				xhr = new XMLHttpRequest() // ie7+等现代浏览器
			} else if (window.ActiveXObject) { // ie5/6，老版Opera
				xhr = new ActiveXObject('Microsft.XMLHTTP')
			}
			xhr.open('GET', url, true);
			for (let [key, value] of Object.entries(head)) {
				//console.log(key, value);
				xhr.setRequestHeader(key, value);
			}
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4) {
					if (xhr.status == 200) {
						var response = xhr.responseText;
						// 在这里处理服务器响应
						success(response);
					} else if (this.status == 404) {
						console.log('网页不存在')
					} else {
						error && error(xhr.status, xhr.responseText);
					}
				}
			};
			xhr.send();
		};
		_fun_.jsonToQueryString = function(json) {
			// 将JSON对象转换为键值对格式
			const params = Object.entries(json);
			// 将键值对格式的数据按照键的字母顺序排序
			params.sort((a, b) => a[0].localeCompare(b[0]));
			// 将排序后的键值对格式数据转换为查询字符串
			const queryString = params.map(param => param.join('=')).join('&');
			return queryString;
		}

		_fun_.down = function(url, call) {
			// 建立对象
			let xhr = xhr = new XMLHttpRequest()
			// 建立一个 GET 请求，异步
			xhr.open('GET', url)
			// 设置返回数据的类型为arraybuffer
			xhr.responseType = 'arraybuffer'
			// 设置请求头值
			//xhr.setRequestHeader(KEYS.JWTToken, getStorageItem(KEYS.JWTToken))
			// 接收到完整的响应数据时触发回调处理函数
			xhr.onload = function() {
				if (xhr.readyState == 4) {
					if (this.status === 200) {
						// # 获取请求头Content-Type的值，用来判断是不是文件流下载
						let type = xhr.getResponseHeader('Content-Type')
						//# application/json;charset=UTF-8：就是指“无类型”，通常的字节流用于数据传输，非文件下载
						if (type === 'application/json;charset=UTF-8') {
							// # this.response为arraybuffer对象，转为uint8数组
							let uint8 = new Uint8Array(this.response)
							// # 解决使用fromCharCode后中文乱码的问题
							let resToString = decodeURIComponent(escape((String.fromCharCode(...uint8))))
							let message = JSON.parse(resToString).message
							//console.log(message)
							call && call(message);
							return
						}
						//# Blob()的第一个参数必须为数组，即便只有一个字符串也必须用数组装起来
						var blob = new Blob([this.response], {
							type: type
						})
						call && call(blob)
					}
				}
			}
		}
		return _fun_;
	});


const AIni = {
	charset: "utf-8"
};

const Wk = ["", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"];

const 精度 = 100;
////////////////对象相关///////////////////////////


/**字符串替换
 * @param {Object} reallyDo
 * @param {Object} replaceWith
 * @param {Object} ignoreCase
 */
String.prototype.replaceAll = function(reallyDo, replaceWith, ignoreCase) {
	if (!RegExp.prototype.isPrototypeOf(reallyDo)) {
		return this.replace(new RegExp(reallyDo, (ignoreCase ? "gi" : "gm")), replaceWith);
	} else {
		return this.replace(reallyDo, replaceWith);
	}
};
/**
 * 盘点字符串开始于 
 * @param {Object} str 开始于 
 */
String.prototype.startWith = function(str) {
	if (str == null || str == "" || this.length == 0 || str.length > this.length)
		return false;
	if (this.substr(0, str.length) == str)
		return true;
	else
		return false;
};
/**
 * 左侧补n个0
 * @param {Object} length
 */
String.prototype.padLeft = function(length) {
	var a = [];
	for (var i = this.length; i < length; i++) {
		a.push("0");
	}
	a.push(this);
	return a.join("");
};
/**
 * 解析jsonstring  成 对象实例
 * @param {Object} length
 */
String.prototype.parse = function(length) {
	try {
		return JSON.parse(this);
	} catch (e) {
		return null;
	}
}
//两端去空格函数  
String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, "");
};







